package com.tzy.gateway.config;
import com.tzy.common.constant.CacheConstant;
import com.tzy.gateway.service.RedisService;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import javax.annotation.Resource;
import java.util.List;
/**
 *  自定义全局过滤器
 */
@Data
@Slf4j
@Component
public class GatewayGlobalFilter implements GlobalFilter, Ordered {
    @Resource
    private RedisService redisService;

    @Value("#{'${filter.exclude}'.split(',')}")
    private List excludeList;
    /**
     * 不拦截登录和注册的请求
     * 该 GlobalFilter会校验请求中是否包含了“token”，如何不包含请求参数“token”则不转发路由，否则执行正常的逻辑。
     * @param exchange 包含request和response对象
     * @param chain 过滤器链
     * @return Mono<Void>
     */

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        DataBufferFactory dataBufferFactory = response.bufferFactory();

        String path = request.getPath().value();//获取请求上下文
        log.info("contextPath="+path);
        log.info("list="+excludeList);
        if(excludeList.contains(path)){
            log.info("过滤器执行放行操作");
            return chain.filter(exchange);
        }
        String uid = request.getHeaders().getFirst(CacheConstant.HEADER_UID);
        log.info("uid="+uid);
        if( !(StringUtils.isBlank(uid)) ){
            String token = request.getHeaders().getFirst(CacheConstant.HEADER_TOKEN);
            //token为空说明未登录， 拦截
            if (StringUtils.isBlank(token)){
                log.info("过滤拦截");
                DataBuffer data = dataBufferFactory.wrap("no login".getBytes());
                return response.writeWith(Mono.just(data));
//                response.setStatusCode(HttpStatus.FORBIDDEN);
//                return response.setComplete();
            }
            log.info("token="+token);
            //token不为空
            //从 redis里取 token,并比较是否一致,是就返回 true
            String cacheToken = redisService.getString(CacheConstant.TOKEN_PREFIX+uid);
            log.info("cacheToken="+cacheToken);
            if( (token.equals(cacheToken))){//token一致
                log.info( "过滤器放行" );
                return chain.filter(exchange);
            }
            log.info( "401 Unauthorized.(没有权限)" );
            DataBuffer data = dataBufferFactory.wrap("no login".getBytes());
            return response.writeWith(Mono.just(data));
//            response.setStatusCode(HttpStatus.UNAUTHORIZED);
//            return response.setComplete();
        }
        log.info( "no login" );
        //        ServerHttpResponse response = exchange.getResponse();

        DataBuffer data = dataBufferFactory.wrap("no login".getBytes());
        return response.writeWith(Mono.just(data));
//        response.setStatusCode(HttpStatus.UNAUTHORIZED);
//        return response.setComplete();
    }
    public Mono<Void> filterDemo(ServerWebExchange exchange, GatewayFilterChain chain) {
        String uid = exchange.getRequest().getHeaders().getFirst("uid");
        if(StringUtils.isBlank(uid)){
            String token = exchange.getRequest().getHeaders().getFirst("token");
            if(StringUtils.isBlank(token)){
                if("1".equals(uid) && "token".equals(token)){
                    return chain.filter(exchange);
                }
            }
        }
        ServerHttpResponse response = exchange.getResponse();
        DataBufferFactory dataBufferFactory = response.bufferFactory();
        DataBuffer data = dataBufferFactory.wrap("no login".getBytes());
        return response.writeWith(Mono.just(data));
    }
    @Override
    public int getOrder() {
        return -100;
    }
}
